package com.test.thread;

import jdk.internal.vm.Continuation;
import jdk.internal.vm.ContinuationScope;

import java.util.function.Consumer;

/**
 * run need add vm option: --enable-preview --add-exports java.base/jdk.internal.vm=ALL-UNNAMED
 */
public class GeneratorDemo {
    public static void main(String[] args) {
        var generator = new Generator<String>(source -> {
            source.yield("A");
            source.yield("B");
            source.yield("C");
        });

        while (generator.hasNext()) {
            System.out.println(generator.next());
            System.out.println("Do something");
        }
    }

    public static class Generator<T> {
        private final ContinuationScope scope;
        private final Continuation continuation;
        private final Source source;

        public boolean hasNext() {
            return !continuation.isDone();
        }

        public T next() {
            var t = source.getValue();
            continuation.run();
            return t;
        }

        public class Source {
            private T value;

            public void yield(T value) {
                this.value = value;
                Continuation.yield(scope);
            }

            public T getValue() {
                return value;
            }
        }

        public Generator(Consumer<Source> consumer) {
            this.scope = new ContinuationScope("Generator");
            this.source = new Source();
            this.continuation = new Continuation(scope, () -> consumer.accept(source));
            this.continuation.run();
        }
    }
}
